iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
Modern Web

前端開發之那些我會的與我不會的技術系列 第 9

JSX在React中的作用以及它的基本語法規則

  • 分享至 

  • xImage
  •  

什麼是JSX

Jsx是一種語法的擴展(syntax extension),讓我們可以在Js裡面寫像是HTML的語法,這些像HTML的語法最終幫助我們產生HTML在畫面上。在React的概念裡,因為網頁應用的互動性越來越高(Js操作畫面HML),所以把Js和畫面寫在一起可以更方便維護,也可以讓彼此component隔離,減少那種改A壞B的問題發生。

為什麼需要JSX

在沒有使用Jsx之前會使用React提供的api來產出畫面,以下產出同樣的畫面兩種不同的寫法

// 使用JSX
const element = (
	<div className="box">
		<h1>哈囉 你好嗎?</h1>
		<h2>真心感謝</h2>
	</div>
)
// 使用 createElement
const H1El= React.createElement(
  'h1',
  {className: 'greeting'},
  '哈囉 你好嗎?'
);
const H2El = React.createElement(
  'h2',
  null,
  '真心感謝'
);
const BoxEl = React.createElement(
  'div',
  {className: 'box'},
  [H1El,H2El]
);

才寫兩行字就要寫這麼多行,createElement是不是很麻煩,而且JSX看起來也跟之前在寫HTML比較像,比較起來親合多了,所以大多數還是會用JSX。

語法

回傳的內容要是單一element

JSX會轉換為JS的物件,我們沒辦法讓funciton回傳超過一個物件,除非有陣列之類的包裹著,所以在這邊道理也是相同,需要在外層加上一個element。

// 正確 O
function App() {
	return <div>
		<h1>哈囉你好嗎</h1>
		<h2>真心感謝</h2>
	</div>
}

// 錯誤 X
function App() {
	<h1>哈囉你好嗎</h1>
	<h2>真心感謝</h2>
}

如果你不想外層包裹著一個無用的element,破壞原本HTML的結構,可以使用********來代替。

import { ****Fragment } from 'react'****

function App() {
	return <****Fragment****>
		<h1>哈囉你好嗎</h1>
		<h2>真心感謝</h2>
	</****Fragment****>
}

// 簡寫
function App() {
	return <>
		<h1>哈囉你好嗎</h1>
		<h2>真心感謝</h2>
	</>
}

可以用瀏覽器的檢查,查看兩者HTML的不同,使用Fragment沒有多餘的div
https://ithelp.ithome.com.tw/upload/images/20230924/20162751R0T92JeWAm.png

tag必須要關閉

function App() {
	return <h1>哈囉你好嗎</h1>
}
// 沒有結尾tag的就要自己關門,像是img、input
function App() {
	return <>
		<img src="abc.jpg" />
		<input type="text" />
	</>
}

JSX的屬性要以駝峰表示

function App() {
	// class在JS是保留字,class要改成className,就跟JS的屬性相同
	// data-*和aria-*比較像是特例沒有駝峰
	return <img src="abc.jpg" className="photo" data-id="123" />
}

在JSX加入JS要以大括號{}包裹,包裹內容必須是表達式

用{}包裹變數,可接在屬性正後面或標籤內容

function App() {
	const person = {
		name: '阿明',
		age: 20,
		img: 'abc.jpg'
	}
	return <>
		<img src={person.img} />
		<h1>{person.name}</h1>
		<p>{person.age}</p>
		<button>click</button>
	</>
}

加入style,樣式以物件表示,也就是說外層的是JSX的大括號,裡面的式樣是物件,樣式也需要以駝峰命名

function App() {
	return <>
		<h1 style={{
			backgroundColor: 'red'
		}}>哈囉</h1>
	</>
}

條件渲染Conditional Rendering

// 方法1 
function App({name, isPass}) {
	if (isPass) {
		return <p>{name} O</p>
	}
	return  <p>{name}</p>
}
// 方法2,3元運算,並可以用()包住多行
function App({name, isPass}) {
	return <p>{isPass ? 
		name : 
		(<del>
			name  + 'O'
		</del>)
	}</p>
}
// 方法3,&&,如果前面是true就會回傳後面element
function App({name, isPass}) {
	return <p>{name} {isPass && 'O'}</p>
}
//但,如果判斷是數字0就不適合用這種方式,react會回傳數字0,可以改用明確判斷>0、===0 或 <0代替
function App({name, count}) {
	return <p>{count > 0 && name}</p>
}

// 方法4,把內容用變數存著
function App({name, isPass}) {
	let content = name;
	if (isPass) {
		content = name + 'o'
	}
	return  <p>{content}</p>
}

渲染一系列同樣結構不同內容的element(Rendering Lists)

return 陣列可以渲染出多個element

可使用map或filter等JS的Array api來回傳陣列

const lyrics = [
	{id: 1, text: '哈囉你好嗎'},
	{id: 2, text: '真心感謝'},
	{id: 3, text: '期待再相逢'},
]

function App() {
	return <ul>
		{ 
			lyrics.map((lyrice) => {
				return <li key={lyrice.id}>{lyrice.text}</li>
			}) 
		}
	</ul>
}

使用List的方法必須在element加上一個獨一無二的key,做為每個item的識別。

注意事項

  • 不建議用array的index最為key,因為如果陣列重新排列或者有刪除元素,index的順序就會改變,舉個例子,如果原本有三個item編號1、2、3,第一個item刪除了,原本的編號2就會變成編號1,原本的編號3就變成編號2,react機制會出錯。
  • item上的key不能改變,因為如果是相同元件,在每次重新渲染時給予不同的key,會有重新渲染相同item的問題

要顯示空的話回傳Null

function App({name, isPass}) {
	if (isPass) {
		return null // 會回傳空白,undefined和false也有相同結果
	}
	return  <p>{name}</p>
}

我不會的JSX

也是這次鐵人賽才去仔細翻了一下JSX文件,原來還有HTML轉JSX的工具可以用,還不熟練的可以上去玩玩看,快速幫助熟悉。

另外,也看到了文件的一段話,有人理解什麼意思嗎?不太理解這邊要表達的內容

React does not reset state when you go from rendering <><Child /></> to [<Child />] or back, or when you go from rendering <><Child /></> to <Child /> and back. This only works a single level deep: for example, going from <><><Child /></></> to <Child /> resets the state. See the precise semantics here.

參考

https://transform.tools/html-to-jsx
https://react.dev/reference/react/Fragment
https://react.dev/learn/rendering-lists
https://react.dev/reference/react-dom/components/common
https://react.dev/learn/conditional-rendering


上一篇
前端開發的進化:從傳統JavaScript到現代前端框架
下一篇
React JSX 中的事件處理程序:基本介紹和語法範例
系列文
前端開發之那些我會的與我不會的技術31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言